package com.zsrt.devbase.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import com.zsrt.devbase.common.utils.ConstantDefine;

public abstract class BaseAjaxController<T> {
	protected Logger logger = Logger.getLogger(this.getClass());

	private static ThreadLocal<HttpServletRequest> currentRequest = new ThreadLocal<HttpServletRequest>();
	private static ThreadLocal<HttpServletResponse> currentResponse = new ThreadLocal<HttpServletResponse>();
	// 设置cookie的默认生命周期
	private static final int COOKIE_MAX_AGE = 7 * 24 * 3600;

	@ModelAttribute
	public void initReqAndRep(HttpServletRequest request, HttpServletResponse response) {
		currentRequest.set(request);
		currentResponse.set(response);
	}

	/**
	 * 统一处理系统异常
	 * 
	 * @param request
	 * @param e
	 * @return
	 */
	@ExceptionHandler
	@ResponseBody
	public Map<String, Object> exceptionHandler(Exception e) {
		logger.error(e, e);
		Map<String, Object> result = new HashMap<String, Object>();
		// 没有权限
		if (e instanceof UnauthorizedException) {
			result.put(ConstantDefine.CHECK_ERROR, ConstantDefine.NO_PERMISSION);
		} else if (e instanceof MaxUploadSizeExceededException) {
			result.put(ConstantDefine.CHECK_ERROR,
					"文件应不大于 " + getFileKB(((MaxUploadSizeExceededException) e).getMaxUploadSize()));
		}
		/**
		 * 此处可以自定义异常 针对service抛出的异常返回一系列的提示信息
		 */
		else {
			result.put(ConstantDefine.SYS_ERROR_KEY, ConstantDefine.SYS_ERR_MSG);
		}
		return result;
	}

	/**
	 * 初始化页面
	 * 
	 * @param model
	 *            向页面传递数据
	 * @return
	 */
	@RequestMapping(value = "/init")
	public abstract String init(Model model);

	/**
	 * 带参数的初始化
	 * 
	 * @param entity
	 * @param model
	 *            向页面传递数据
	 * @return
	 */
	/*@RequestMapping(value = "/init")
	public abstract String init(T entity, Model model);*/

	/**
	 * 条件查询数据
	 * 
	 * @param entity
	 * @return
	 */
	@RequestMapping(value = "/list")
	public abstract Object queryByEntity(T entity);

	/**
	 * 先验证再保存
	 * 
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST)
	public abstract ResponseEntity<Map<String, Object>> save(@Valid T entity, BindingResult bindingResult);

	/**
	 * 初始化更新页面
	 * 
	 * @param id
	 *            主键
	 * @return 用户信息
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "{id}", method = RequestMethod.GET)
	public abstract T updateInit(@PathVariable("id") String id);

	/**
	 * 更新实体
	 * 
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT)
	public abstract ResponseEntity<Map<String, Object>> update(@Valid T entity, BindingResult bindingResult);

	/**
	 * 删除
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(method = RequestMethod.DELETE)
	public abstract ResponseEntity<Map<String, Object>> delete(@RequestBody List<String> id);

	/**
	 * 添加session
	 * 
	 * @param key
	 * @param objValue
	 */
	public void addSession(String key, Object objValue) {
		HttpSession session = getSession();
		session.setAttribute(key, objValue);
	}

	/**
	 * 根据key获取session
	 * 
	 * @param key
	 * @return
	 */
	public Object getSession(String key) {
		HttpSession session = getSession();
		Object obj = null;
		if (!StringUtils.isEmpty(key)) {
			obj = session.getAttribute(key);
		}
		return obj;
	}

	/**
	 * 取得当前登录用户的编号
	 * 
	 * @return
	 */
	public String getLoginPersonCode() {
		return (String) this.getSession(ConstantDefine.PERSONCODE_SESSION);
	}

	/**
	 * 根据key删除session
	 * 
	 * @param key
	 */
	public void removeSession(String key) {
		HttpSession session = getSession();
		if (!StringUtils.isEmpty(key)) {
			session.removeAttribute(key);
		}
	}

	/**
	 * 获取session对象
	 * 
	 * @return
	 */
	private HttpSession getSession() {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
		if (request == null) {
			return null;
		}
		HttpSession session = request.getSession(false);
		if (session == null) {
			throw new RuntimeException("session已失效！");
		}
		return session;
	}

	private String getFileKB(long byteFile) {
		if (byteFile == 0)
			return "0KB";
		long kb = 1024;
		return "" + byteFile / kb + "KB";
	}

	@SuppressWarnings("unused")
	private String getFileMB(long byteFile) {
		if (byteFile == 0)
			return "0MB";
		long mb = 1024 * 1024;
		return "" + byteFile / mb + "MB";
	}

	public HttpServletRequest getRequest() {
		return (HttpServletRequest) currentRequest.get();
	}

	public HttpServletResponse getResponse() {
		return (HttpServletResponse) currentResponse.get();
	}

	/**
	 * 添加cookie
	 * @author leixin
	 * @createTime 下午2:46:07
	 * @param key
	 * @param value
	 * @param maxAge
	 */
	public void addCookie(String key, String value, int maxAge) {
		HttpServletResponse response = getResponse();
		String encodeValue = null;
		try {
			//设置cookie编码格式
			 encodeValue = URLEncoder.encode(value, "UTF-8");
			
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			logger.error("编码转换错误,cookie失败");
			e.printStackTrace();
		}
		if (null != encodeValue) {
			Cookie cookie = new Cookie(key, encodeValue);
			//设置cookie共享
			cookie.setPath("/");
			if (maxAge > 0) {
				cookie.setMaxAge(maxAge);
			}
			response.addCookie(cookie);
		}

	}

	/**
	 * 添加cookie
	 * 默认的生命周期为：7 * 24 * 3600 秒
	 * @author leixin
	 * @createTime 下午2:45:50
	 * @param key
	 * @param value
	 */
	public void addCookie(String key, String value) {
		addCookie(key, value, COOKIE_MAX_AGE);
	}

	/**
	 * 根据key删除cookie
	 * @author leixin
	 * @createTime 下午2:45:18
	 * @param key
	 */
	public void removeCookie(String key) {
		HttpServletResponse response = getResponse();
		Cookie uid = new Cookie(key, null);
		//设置共享
		uid.setPath("/");
		uid.setMaxAge(0);
		response.addCookie(uid);
	}

	
	/**
	 * 根据key获取cookie 的值
	 * @author leixin
	 * @createTime 下午2:44:54
	 * @param key 
	 * @return
	 */
	public String getCookieByKey(String key) {
		HttpServletRequest request = getRequest();
		Cookie cookies[] = request.getCookies();
		for (Cookie cookie : cookies) {
			if (cookie.getName().equals(key)) {
				return cookie.getValue();
			}
		}
		return null;
	}
}
